local oo = require("SharedLibs.BaseLib")
local co = require("SharedLibs.CoroLib")

AsyncOp = require("SharedLibs.AsyncOp");

--- WaitSignal Class ---
local WaitSignal = oo.Class()
WaitSignal.name = "WaitSignal";
oo.ClassExtends(WaitSignal, AsyncOp)

function co.WaitSignal(siganl, predicate)
	return oo.New(WaitSignal, siganl, predicate);
end

--- 如果retTuple为true, 那么GetReturn直接返回tuple(table)而不是...
function WaitSignal.prototype.constructor(self, signal, predicate, retTuple)
	WaitSignal._ss.prototype.constructor(self)
	
	self._state = co.AsyncOpState.Ready;
	self._signal = signal;
	self._predicate = predicate;	
	self._returnValue = nil;
	self._onSignal = nil;
	
	self._retTuple = retTuple;
end

function WaitSignal.prototype.Start(self, endCallback, parent)
	WaitSignal._ss.prototype.Start(self, endCallback, parent);

	self._onSignal = function(...) 
		if self._state ~= co.AsyncOpState.Executing then return end;
		if self._predicate ~= nil and not self._predicate(...) then return end;
		
		local count = select("#",...);
		if count <= 1 then 
			local value = ...; --- Fetch first value
			self._returnValue = value;
		else
			self._hasVarReturn = true;
			self._returnValue = {...};
		end

		if self._continuation ~= nil then 
			self:_doStop(true);	
		end;
	end;

	self._signal:On(self._onSignal);
end

function WaitSignal.prototype.GetReturn(self)
	if self._hasVarReturn and not self._retTuple then
		return table.unpack(self._returnValue);
	else
		return self._returnValue;
	end
end

function WaitSignal.prototype._onStop(self)
	self._signal:Off(self._onSignal);
end

return WaitSignal;
